package de.fhd.pms;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.log4j.Logger;

/**
 * Klasse zum anlegen der benötigten Datenbank in MySQL.
 * <p>
 * Anlegen einer neuen Datenbank, sofern diese noch nicht vorhanden ist. Startup
 * legt eine neue Datenbank namens <i>"carsharingV1"</i> an, sofern diese
 * Datenbank noch nicht in MySQL existiert.
 * </p>
 * @author Martin Schmid
 * @author Florian Schachner
 */
public class Startup {

	/*
	 * Definition eines Logger für die Klasse "Startup".
	 * Dieser Logger gilt ausschließlich für die Klasse Startup. Über die 
	 * Instanz "log" können dann Informationen auf der Konsole ausgegeben
	 * werden. Die Klassenmethode getLogger benötigt als Parameter die Klasse,
	 * für die die Instanz zuständig ist (Startup.class). Um den Logger nutzen
	 * zu können, muss die Klasse "org.apache.log4j.Logger" importiert werden
	 * (Achtung: es gibt verschiedene!)
	 * 
	 * Welche Meldungen in der Console gezeigt werden, ist in der Datei
	 * "log4j.properties" eingestellt (Hierarchie beachten):
	 * log4j.rootLogger=debug, stdout, logfile
	 * fatal (schwerwiegend) -> log.fatal("Startup wird initialisiert!");
	 * error -> log.error("Startup wird initialisiert!");
	 * warn -> log.warn("Startup wird initialisiert!");
	 * info -> log.info("Startup wird initialisiert!");
	 * debug -> log.debug("Startup wird initialisiert!); (nicht schwerwiegend);
	 
	 * Eclipse-Bedienungshinweise:
	 * Strg+. (Hier springt man von Fehler zu Fehler)
	 * Strg+1 (Anzeige der Vorschlagswerte)
	 */
	private static Logger log = Logger.getLogger(Startup.class);

	/*
	 * DEFINITON DER PRIVATEN ATTRIBUTE Hier kommt das Hollywood-Prinzip ins
	 * Spiel: DEPENDENCY INJECTION: Spring ruft die Klasse auf und füttert die Werte (zuvor
	 * definierte Properties) (Damit dies funktioniert müssen die SETTER-Methoden definiert sein) 
	 * (GETTER-Methoden sind in diesem Fall nicht notwendig)
	 */

	private String driverClass;
	private String user;
	private String password;
	private String defaultDBurl;
	private String newDB;

	/*
	 * DEFINITON DER SETTER-METHODEN 
	 * Setter-Methoden sind notwendig, damit die Properties (definiert in bean) bei der Instanziierung der Klasse
	 * injiziert werden können
	 */
	public void setDriverClass(String driverClass) {
		this.driverClass = driverClass;
	}

	public void setUser(String user) {
		this.user = user;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setDefaultDBurl(String defaultDBurl) {
		this.defaultDBurl = defaultDBurl;
	}

	public void setNewDB(String newDB) {
		this.newDB = newDB;
	}

	/**
	 * init-Methode zur Erzeugung einer Datenbank für die Applikation.
	 * <p>
	 * Diese Methode legt die benötigte Carsharing-Datenbank neu in der
	 * MYSQL-Datenbank an. Spring versucht beim ausführen der bean mit der
	 * id="init" die Methode "initDB" der Klasse "Startup" aufzurufen. Diese
	 * Methode existiert jedoch in diesem Moment noch nicht. Deshalb wird hier
	 * die Methode "initDB" definiert.
	 * 
	 * @exception InstantiationException
	 *                String der mitgegeben wurde ist fehlerhaft bzw. Ziel
	 *                (MySQL-Datenbank) existiert nicht
	 * @exception IllegalAccessException
	 *                Username und oder Passwort stimmen nicht überein
	 * @exception ClassNotFoundException
	 *                Treiberklasse kann nicht geöffnet werden
	 * @exception SQLException
	 *                Fehlermeldung, falls die übergebene SQL-Anweisung nicht
	 *                ausgeführt werden konnte (Fehlerhaftes SQL-Statement)
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	public void initDB() {

		/*
		 * Test, ob properties der bean "init" korrekt injekziert wurde
		 * log.fatal(password); //2011-11-02 09:57:26,813 FATAL
		 * [de.fhd.pms.Startup] - <> log.error("DB wird initialisiert!");
		 * log.warn("User: " + user); //2011-11-02 09:57:26,813 WARN
		 * [de.fhd.pms.Startup] - <User: root> log.info("Die Standard DB: " +
		 * defaultDBurl); //2011-11-02 09:57:26,813 INFO [de.fhd.pms.Startup] -
		 * <Die Standard DB: jdbc:mysql://localhost:3306/mysql> log.info(newDB);
		 * //2011-11-02 09:57:26,813 INFO [de.fhd.pms.Startup] - <fahrtenbuchVS>
		 * log.debug(driverClass); //2011-11-02 09:57:26,813 DEBUG
		 * [de.fhd.pms.Startup] - <com.mysql.jdbc.Driver>
		 */

		log.info("DB wird initialisiert! Neue Datenbank = " + newDB);

		// DATANBANKANLAGE AUSPROGRAMMIEREN
		try {
			// 1) Datenbanktreiber instanziieren
			Class.forName(driverClass).newInstance();

			// 2) Verbindung zur Datenbank instanziieren (Fehlerbehandlung durch
			// zusätzliche Catch -> kein Try
			Connection con = DriverManager.getConnection(defaultDBurl, user, password);

			// 3) Verwenden der Connection und senden einer Anweisung
			// ("Create Database ...") an die Datenbank
			// stmt.execute(sqlString) führt den übergebene SQL-Anweisung in der
			// Datenbank aus
			Statement stmt = con.createStatement();
			String sqlString = "CREATE DATABASE " + newDB;
			stmt.execute(sqlString);
			con.commit();
			con.close();
			log.info("Die Datenbank wurde angelegt!");

		} catch (InstantiationException e) {
			// InstantiationException: String der mitgegeben wurde ist Fehlerhaft bzw. Ziel existiert nicht
			log.error("Die Treiberklasse kann nicht geöffnet werden. " + e.getMessage());
		} catch (IllegalAccessException e) {
			// IllegalAccessException: Username und oder Passwort stimmen nicht überein
			log.error("Die Treiberklasse kann nicht geöffnet werden. " + e.getMessage());
		} catch (ClassNotFoundException e) {
			// Treiberklasse kann nicht geöffnet werden (Fehler: ???)
			log.error("Die Treiberklasse kann nicht geöffnet werden. "+ e.getMessage());
		} catch (SQLException e) {
			// Fehlermeldung, falls die übergebene SQL-Anweisung nicht ausgeführt werden konnte (evtl. Fehlerhaft)
			log.error("Keine Verbindung zur Datenbank oder das Anlegen hat nicht funktioniert. " + e.getMessage());
		}

	}
}
